import random
from PIL import Image, ImageDraw, ImageFont
import string
import io
from django.http import HttpResponse


class CaptchaGenerator:
    def __init__(self, width=120, height=60, length=4, font_size=40):
        self.width = width
        self.height = height
        self.length = length
        self.font_size = font_size
        self.characters = string.ascii_letters + string.digits

    def generate_code(self):
        return ''.join(random.sample(self.characters, self.length))

    def generate_image(self, code):
        # 创建图像
        image = Image.new('RGB', (self.width, self.height),
                          (random.randint(200, 255), random.randint(200, 255), random.randint(200, 255)))
        draw = ImageDraw.Draw(image)

        # 绘制干扰线
        for _ in range(random.randint(3, 5)):
            x1 = random.randint(0, self.width)
            y1 = random.randint(0, self.height)
            x2 = random.randint(0, self.width)
            y2 = random.randint(0, self.height)
            draw.line((x1, y1, x2, y2), fill=(random.randint(0, 200), random.randint(0, 200), random.randint(0, 200)))

        # 绘制干扰点
        for _ in range(random.randint(50, 100)):
            draw.point((random.randint(0, self.width), random.randint(0, self.height)),
                       fill=(random.randint(0, 200), random.randint(0, 200), random.randint(0, 200)))

        # 绘制文字
        try:
            font = ImageFont.truetype('arial.ttf', self.font_size)
        except IOError:
            font = ImageFont.load_default()

        for i, char in enumerate(code):
            draw.text((10 + i * (self.width - 20) / self.length,
                       random.randint(5, self.height - self.font_size - 5)),
                      char,
                      font=font,
                      fill=(random.randint(0, 150), random.randint(0, 150), random.randint(0, 150)))

        return image

    def get_captcha(self):
        code = self.generate_code()
        image = self.generate_image(code)
        buffer = io.BytesIO()
        image.save(buffer, 'PNG')
        buffer.seek(0)
        return code, buffer
